<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>class IO::Buffer - RDoc Documentation</title>


<script src="../js/navigation.js" defer></script>
<script src="../js/search.js" defer></script>
<script src="../js/search_index.js" defer></script>
<script src="../js/searcher.js" defer></script>
<script src="../js/darkfish.js" defer></script>

<script src="../js/jquery-3.2.0.min.js"></script>

<script src="../js/vue.min.js"></script>
<script src="../js/js.cookie.min.js"></script>

<link href="../css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="../css/rdoc.css" rel="stylesheet">
<link href="../css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "../";
  var index_rel_prefix = "../";
  var darkModeCsseHref = "../css/rdoc-dm.css"
  var defaultModeCssHref = "../css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="class">
  <!-- this is class.html -->

  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0-preview2 NOT FOUND -->
  </div> <!-- end action bar -->

  <div class='wrapper hdiv'>

    


    <nav id='vapp' role="navigation">
    <div id="project-navigation">
      <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="../index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="../table_of_contents.html#pages">Pages</a>
    <a href="../table_of_contents.html#classes">Classes</a>
    <a href="../table_of_contents.html#methods">Methods</a>
  </div>
</div>

      <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

    </div>


    

    <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>
    <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
      <div id="class-metadata">
        
        
<div id="parent-class-section" class="nav-section">
  <h3>Parent</h3>

  <p class="link"><a href="../Object.html">Object</a>
</div>

        
<div id="includes-section" class="nav-section">
  <h3>Included Modules</h3>

  <ul class="link-list">
    <li><a class="include" href="../Comparable.html">Comparable</a>
  </ul>
</div>

        
        
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
  <h3>Methods</h3>

  <ul class="link-list" role="directory">
    <li ><a href="#method-c-for">::for</a>
    <li ><a href="#method-c-map">::map</a>
    <li ><a href="#method-c-new">::new</a>
    <li ><a href="#method-c-size_of">::size_of</a>
    <li ><a href="#method-c-string">::string</a>
    <li ><a href="#method-i-26">#&amp;</a>
    <li ><a href="#method-i-3C-3D-3E">#&lt;=&gt;</a>
    <li ><a href="#method-i-5E">#^</a>
    <li ><a href="#method-i-and-21">#and!</a>
    <li ><a href="#method-i-clear">#clear</a>
    <li ><a href="#method-i-copy">#copy</a>
    <li ><a href="#method-i-each">#each</a>
    <li ><a href="#method-i-each_byte">#each_byte</a>
    <li ><a href="#method-i-empty-3F">#empty?</a>
    <li ><a href="#method-i-external-3F">#external?</a>
    <li ><a href="#method-i-free">#free</a>
    <li ><a href="#method-i-get_string">#get_string</a>
    <li ><a href="#method-i-get_value">#get_value</a>
    <li ><a href="#method-i-get_values">#get_values</a>
    <li ><a href="#method-i-hexdump">#hexdump</a>
    <li ><a href="#method-i-initialize_copy">#initialize_copy</a>
    <li ><a href="#method-i-inspect">#inspect</a>
    <li ><a href="#method-i-internal-3F">#internal?</a>
    <li ><a href="#method-i-locked">#locked</a>
    <li ><a href="#method-i-locked-3F">#locked?</a>
    <li ><a href="#method-i-mapped-3F">#mapped?</a>
    <li ><a href="#method-i-not-21">#not!</a>
    <li ><a href="#method-i-null-3F">#null?</a>
    <li ><a href="#method-i-or-21">#or!</a>
    <li ><a href="#method-i-pread">#pread</a>
    <li ><a href="#method-i-pwrite">#pwrite</a>
    <li ><a href="#method-i-read">#read</a>
    <li ><a href="#method-i-readonly-3F">#readonly?</a>
    <li ><a href="#method-i-resize">#resize</a>
    <li ><a href="#method-i-set_string">#set_string</a>
    <li ><a href="#method-i-set_value">#set_value</a>
    <li ><a href="#method-i-set_values">#set_values</a>
    <li ><a href="#method-i-shared-3F">#shared?</a>
    <li ><a href="#method-i-size">#size</a>
    <li ><a href="#method-i-slice">#slice</a>
    <li ><a href="#method-i-to_s">#to_s</a>
    <li ><a href="#method-i-transfer">#transfer</a>
    <li ><a href="#method-i-valid-3F">#valid?</a>
    <li ><a href="#method-i-values">#values</a>
    <li ><a href="#method-i-write">#write</a>
    <li ><a href="#method-i-xor-21">#xor!</a>
    <li ><a href="#method-i-7C">#|</a>
    <li ><a href="#method-i-~">#~</a>
  </ul>
</div>

      </div>
     </div>
    </nav>


    <div id='extraz'><div class='adzbox-index'  >
      
     </div>         
    </div>

    <main role="main" aria-labelledby="class-IO::Buffer">
    <h1 id="class-IO::Buffer" class="class">
      class IO::Buffer
    </h1>

    <section class="description">
    
<p><a href="Buffer.html"><code>IO::Buffer</code></a> is a low-level efficient buffer for input/output. There are three ways of using buffer:</p>
<ul><li>
<p>Create an empty buffer with <a href="Buffer.html#method-c-new"><code>::new</code></a>, fill it with buffer using <a href="Buffer.html#method-i-copy"><code>copy</code></a> or <a href="Buffer.html#method-i-set_value"><code>set_value</code></a>, <a href="Buffer.html#method-i-set_string"><code>set_string</code></a>, get buffer with <a href="Buffer.html#method-i-get_string"><code>get_string</code></a>;</p>
</li><li>
<p>Create a buffer mapped to some string with <a href="Buffer.html#method-c-for"><code>::for</code></a>, then it could be used both for reading with <a href="Buffer.html#method-i-get_string"><code>get_string</code></a> or <a href="Buffer.html#method-i-get_value"><code>get_value</code></a>, and writing (writing will change the source string, too);</p>
</li><li>
<p>Create a buffer mapped to some file with <a href="Buffer.html#method-c-map"><code>::map</code></a>, then it could be used for reading and writing the underlying file.</p>
</li></ul>

<p>Interaction with string and file memory is performed by efficient low-level C mechanisms like ‘memcpy`.</p>

<p>The class is meant to be an utility for implementing more high-level mechanisms like Fiber::SchedulerInterface#io_read and Fiber::SchedulerInterface#io_write.</p>

<p><strong>Examples of usage:</strong></p>

<p>Empty buffer:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">8</span>)  <span class="ruby-comment"># create empty 8-byte buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5d1a5c50+8 INTERNAL&gt;</span>
<span class="ruby-comment"># ...</span>
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># &lt;IO::Buffer 0x0000555f5d156ab0+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 00 00 00 00 00</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;test&#39;</span>, <span class="ruby-value">2</span>) <span class="ruby-comment"># put there bytes of the &quot;test&quot; string, starting from offset 2</span>
<span class="ruby-comment"># =&gt; 4</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>  <span class="ruby-comment"># get the result</span>
<span class="ruby-comment"># =&gt; &quot;\x00\x00test\x00\x00&quot;</span>
</pre>

<p>Buffer from string:</p>

<pre class="ruby"><span class="ruby-identifier">string</span> = <span class="ruby-string">&#39;buffer&#39;</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007f3f02be9b18+4 SLICE&gt;</span>
<span class="ruby-comment"># ...</span>
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007f3f02be9b18+4 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  64 61 74 61                                     buffer</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>(<span class="ruby-value">2</span>)  <span class="ruby-comment"># read content starting from offset 2</span>
<span class="ruby-comment"># =&gt; &quot;ta&quot;</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;---&#39;</span>, <span class="ruby-value">1</span>) <span class="ruby-comment"># write content, starting from offset 1</span>
<span class="ruby-comment"># =&gt; 3</span>
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007f3f02be9b18+4 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  64 2d 2d 2d                                     d---</span>
<span class="ruby-identifier">string</span>  <span class="ruby-comment"># original string changed, too</span>
<span class="ruby-comment"># =&gt; &quot;d---&quot;</span>
</pre>

<p>Buffer from file:</p>

<pre class="ruby"><span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span>(<span class="ruby-string">&#39;test.txt&#39;</span>, <span class="ruby-string">&#39;test buffer&#39;</span>)
<span class="ruby-comment"># =&gt; 9</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">map</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;test.txt&#39;</span>))
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007f3f0768c000+9 MAPPED IMMUTABLE&gt;</span>
<span class="ruby-comment"># ...</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>(<span class="ruby-value">5</span>, <span class="ruby-value">2</span>) <span class="ruby-comment"># read 2 bytes, starting from offset 5</span>
<span class="ruby-comment"># =&gt; &quot;da&quot;</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;---&#39;</span>, <span class="ruby-value">1</span>) <span class="ruby-comment"># attempt to write</span>
<span class="ruby-comment"># in `set_string&#39;: Buffer is not writable! (IO::Buffer::AccessError)</span>

<span class="ruby-comment"># To create writable file-mapped buffer</span>
<span class="ruby-comment"># Open file for read-write, pass size, offset, and flags=0</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">map</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;test.txt&#39;</span>, <span class="ruby-string">&#39;r+&#39;</span>), <span class="ruby-value">9</span>, <span class="ruby-value">0</span>, <span class="ruby-value">0</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;---&#39;</span>, <span class="ruby-value">1</span>)
<span class="ruby-comment"># =&gt; 3 -- bytes written</span>
<span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-string">&#39;test.txt&#39;</span>)
<span class="ruby-comment"># =&gt; &quot;t--- buffer&quot;</span>
</pre>

<p><strong>The class is experimental and the interface is subject to change.</strong></p>

    </section>

      <section id="5Buntitled-5D" class="documentation-section">


      <section class="constants-list">
      <header>
      <h3>Constants</h3>
      </header>
      <dl>
          <dt id="BIG_ENDIAN">BIG_ENDIAN
          <dd>
          <dt id="DEFAULT_SIZE">DEFAULT_SIZE
          <dd>
          <dt id="EXTERNAL">EXTERNAL
          <dd>
          <dt id="HOST_ENDIAN">HOST_ENDIAN
          <dd>
          <dt id="INTERNAL">INTERNAL
          <dd>
          <dt id="LITTLE_ENDIAN">LITTLE_ENDIAN
          <dd>
          <dt id="LOCKED">LOCKED
          <dd>
          <dt id="MAPPED">MAPPED
          <dd>
          <dt id="NETWORK_ENDIAN">NETWORK_ENDIAN
          <dd>
          <dt id="PAGE_SIZE">PAGE_SIZE
          <dd>
          <dt id="PRIVATE">PRIVATE
          <dd>
          <dt id="READONLY">READONLY
          <dd>
          <dt id="SHARED">SHARED
          <dd>
        </dl>
        </section>



                <section id="public-class-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Class Methods</h3>
                </header>

                  <div id="method-c-for" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          IO::Buffer.for(string) &rarr; readonly io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          IO::Buffer.for(string) {|io_buffer| ... read/write io_buffer ...}
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Creates a <a href="Buffer.html"><code>IO::Buffer</code></a> from the given string’s memory. Without a block a frozen internal copy of the string is created efficiently and used as the buffer source. When a block is provided, the buffer is associated directly with the string’s internal buffer and updating the buffer will update the string.</p>

<p>Until <a href="Buffer.html#method-i-free"><code>free</code></a> is invoked on the buffer, either explicitly or via the garbage collector, the source string will be locked and cannot be modified.</p>

<p>If the string is frozen, it will create a read-only buffer which cannot be modified. If the string is shared, it may trigger a copy-on-write when using the block form.</p>

<pre class="ruby"><span class="ruby-identifier">string</span> = <span class="ruby-string">&#39;test&#39;</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">external?</span> <span class="ruby-comment">#=&gt; true</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>(<span class="ruby-value">0</span>, <span class="ruby-value">1</span>)
<span class="ruby-comment"># =&gt; &quot;t&quot;</span>
<span class="ruby-identifier">string</span>
<span class="ruby-comment"># =&gt; &quot;best&quot;</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">resize</span>(<span class="ruby-value">100</span>)
<span class="ruby-comment"># in `resize&#39;: Cannot resize external buffer! (IO::Buffer::AccessError)</span>

<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">buffer</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&quot;T&quot;</span>)
  <span class="ruby-identifier">string</span>
  <span class="ruby-comment"># =&gt; &quot;Test&quot;</span>
<span class="ruby-keyword">end</span>
</pre>

                              <div class="method-source-code" id="for-source">
            <pre>VALUE
rb_io_buffer_type_for(VALUE klass, VALUE string)
{
    StringValue(string);

    // If the string is frozen, both code paths are okay.
    // If the string is not frozen, if a block is not given, it must be frozen.
    if (rb_block_given_p()) {
        struct io_buffer_for_yield_instance_arguments arguments = {
            .klass = klass,
            .string = string,
            .instance = Qnil,
            .flags = 0,
        };

        return rb_ensure(io_buffer_for_yield_instance, (VALUE)&amp;arguments, io_buffer_for_yield_instance_ensure, (VALUE)&amp;arguments);
    }
    else {
        // This internally returns the source string if it&#39;s already frozen.
        string = rb_str_tmp_frozen_acquire(string);
        return io_buffer_for_make_instance(klass, string, RB_IO_BUFFER_READONLY);
    }
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-map" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          IO::Buffer.map(file, [size, [offset, [flags]]]) &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Create an <a href="Buffer.html"><code>IO::Buffer</code></a> for reading from <code>file</code> by memory-mapping the file. <code>file_io</code> should be a <code>File</code> instance, opened for reading.</p>

<p>Optional <code>size</code> and <code>offset</code> of mapping can be specified.</p>

<p>By default, the buffer would be immutable (read only); to create a writable mapping, you need to open a file in read-write mode, and explicitly pass <code>flags</code> argument without IO::Buffer::IMMUTABLE.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span>(<span class="ruby-string">&#39;test.txt&#39;</span>, <span class="ruby-string">&#39;test&#39;</span>)

<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">map</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;test.txt&#39;</span>), <span class="ruby-keyword">nil</span>, <span class="ruby-value">0</span>, <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span><span class="ruby-operator">::</span><span class="ruby-constant">READONLY</span>)
<span class="ruby-comment"># =&gt; #&lt;IO::Buffer 0x00000001014a0000+4 MAPPED READONLY&gt;</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">readonly?</span>   <span class="ruby-comment"># =&gt; true</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>
<span class="ruby-comment"># =&gt; &quot;test&quot;</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;b&#39;</span>, <span class="ruby-value">0</span>)
<span class="ruby-comment"># `set_string&#39;: Buffer is not writable! (IO::Buffer::AccessError)</span>

<span class="ruby-comment"># create read/write mapping: length 4 bytes, offset 0, flags 0</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">map</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;test.txt&#39;</span>, <span class="ruby-string">&#39;r+&#39;</span>), <span class="ruby-value">4</span>, <span class="ruby-value">0</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;b&#39;</span>, <span class="ruby-value">0</span>)
<span class="ruby-comment"># =&gt; 1</span>

<span class="ruby-comment"># Check it</span>
<span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-string">&#39;test.txt&#39;</span>)
<span class="ruby-comment"># =&gt; &quot;best&quot;</span>
</pre>

<p>Note that some operating systems may not have cache coherency between mapped buffers and file reads.</p>

                              <div class="method-source-code" id="map-source">
            <pre>static VALUE
io_buffer_map(int argc, VALUE *argv, VALUE klass)
{
    rb_check_arity(argc, 1, 4);

    // We might like to handle a string path?
    VALUE io = argv[0];

    size_t size;
    if (argc &gt;= 2 &amp;&amp; !RB_NIL_P(argv[1])) {
        size = RB_NUM2SIZE(argv[1]);
    }
    else {
        rb_off_t file_size = rb_file_size(io);

        // Compiler can confirm that we handled file_size &lt; 0 case:
        if (file_size &lt; 0) {
            rb_raise(rb_eArgError, &quot;Invalid negative file size!&quot;);
        }
        // Here, we assume that file_size is positive:
        else if ((uintmax_t)file_size &gt; SIZE_MAX) {
            rb_raise(rb_eArgError, &quot;File larger than address space!&quot;);
        }
        else {
            // This conversion should be safe:
            size = (size_t)file_size;
        }
    }

    rb_off_t offset = 0;
    if (argc &gt;= 3) {
        offset = NUM2OFFT(argv[2]);
    }

    enum rb_io_buffer_flags flags = 0;
    if (argc &gt;= 4) {
        flags = RB_NUM2UINT(argv[3]);
    }

    return rb_io_buffer_map(io, size, offset, flags);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-new" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          IO::Buffer.new([size = DEFAULT_SIZE, [flags = 0]]) &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Create a new zero-filled <a href="Buffer.html"><code>IO::Buffer</code></a> of <code>size</code> bytes. By default, the buffer will be <em>internal</em>: directly allocated chunk of the memory. But if the requested <code>size</code> is more than OS-specific <a href="Buffer.html#PAGE_SIZE"><code>IO::Buffer::PAGE_SIZE</code></a>, the buffer would be allocated using the virtual memory mechanism (anonymous <code>mmap</code> on Unix, <code>VirtualAlloc</code> on Windows). The behavior can be forced by passing <a href="Buffer.html#MAPPED"><code>IO::Buffer::MAPPED</code></a> as a second parameter.</p>

<p>Examples</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">4</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000055b34497ea10+4 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 00                                     ....</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>(<span class="ruby-value">0</span>, <span class="ruby-value">1</span>) <span class="ruby-comment"># =&gt; &quot;\x00&quot;</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&quot;test&quot;</span>)
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000055b34497ea10+4 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  74 65 73 74                                     test</span>
</pre>

                              <div class="method-source-code" id="new-source">
            <pre>VALUE
rb_io_buffer_initialize(int argc, VALUE *argv, VALUE self)
{
    io_buffer_experimental();

    rb_check_arity(argc, 0, 2);

    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    size_t size;

    if (argc &gt; 0) {
        size = RB_NUM2SIZE(argv[0]);
    }
    else {
        size = RUBY_IO_BUFFER_DEFAULT_SIZE;
    }

    enum rb_io_buffer_flags flags = 0;
    if (argc &gt;= 2) {
        flags = RB_NUM2UINT(argv[1]);
    }
    else {
        flags |= io_flags_for_size(size);
    }

    io_buffer_initialize(buffer, NULL, size, flags, Qnil);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-size_of" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          size_of(buffer_type) &rarr; byte size
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          size_of(array of buffer_type) &rarr; byte size
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Returns the size of the given buffer type(s) in bytes.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">size_of</span>(<span class="ruby-value">:u32</span>) <span class="ruby-comment"># =&gt; 4</span>
<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">size_of</span>([<span class="ruby-value">:u32</span>, <span class="ruby-value">:u32</span>]) <span class="ruby-comment"># =&gt; 8</span>
</pre>

                              <div class="method-source-code" id="size_of-source">
            <pre>static VALUE
io_buffer_size_of(VALUE klass, VALUE buffer_type)
{
    if (RB_TYPE_P(buffer_type, T_ARRAY)) {
        size_t total = 0;
        for (long i = 0; i &lt; RARRAY_LEN(buffer_type); i++) {
            total += io_buffer_buffer_type_size(RB_SYM2ID(RARRAY_AREF(buffer_type, i)));
        }
        return SIZET2NUM(total);
    }
    else {
        return SIZET2NUM(io_buffer_buffer_type_size(RB_SYM2ID(buffer_type)));
    }
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-c-string" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          IO::Buffer.string(length) {|io_buffer| ... read/write io_buffer ...} &rarr; string
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Creates a new string of the given length and yields a <a href="Buffer.html"><code>IO::Buffer</code></a> instance to the block which uses the string as a source. The block is expected to write to the buffer and the string will be returned.</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">string</span>(<span class="ruby-value">4</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">buffer</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&quot;Ruby&quot;</span>)
<span class="ruby-keyword">end</span>
<span class="ruby-comment"># =&gt; &quot;Ruby&quot;</span>
</pre>

                              <div class="method-source-code" id="string-source">
            <pre>VALUE
rb_io_buffer_type_string(VALUE klass, VALUE length)
{
    VALUE string = rb_str_new(NULL, RB_NUM2LONG(length));

    struct io_buffer_for_yield_instance_arguments arguments = {
        .klass = klass,
        .string = string,
        .instance = Qnil,
    };

    rb_ensure(io_buffer_for_yield_instance, (VALUE)&amp;arguments, io_buffer_for_yield_instance_ensure, (VALUE)&amp;arguments);

    return string;
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

                <section id="public-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Instance Methods</h3>
                </header>

                  <div id="method-i-26" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          source &amp; mask &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate a new buffer the same size as the source by applying the binary AND operation to the source, using the mask, repeating as necessary.</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>) <span class="ruby-operator">&amp;</span> <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;\xFF\x00\x00\xFF&quot;</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00005589b2758480+4 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  31 00 00 34 35 00 00 38 39 00                   1..45..89.</span>
</pre>

                              <div class="method-source-code" id="26-source">
            <pre>static VALUE
io_buffer_and(VALUE self, VALUE mask)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    struct rb_io_buffer *mask_buffer = NULL;
    TypedData_Get_Struct(mask, struct rb_io_buffer, &amp;rb_io_buffer_type, mask_buffer);

    io_buffer_check_mask(mask_buffer);

    VALUE output = rb_io_buffer_new(NULL, buffer-&gt;size, io_flags_for_size(buffer-&gt;size));
    struct rb_io_buffer *output_buffer = NULL;
    TypedData_Get_Struct(output, struct rb_io_buffer, &amp;rb_io_buffer_type, output_buffer);

    memory_and(output_buffer-&gt;base, buffer-&gt;base, buffer-&gt;size, mask_buffer-&gt;base, mask_buffer-&gt;size);

    return output;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-3C-3D-3E" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          &lt;=&gt;(other) &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Buffers are compared by size and exact contents of the memory they are referencing using <code>memcmp</code>.</p>

                              <div class="method-source-code" id="3C-3D-3E-source">
            <pre>static VALUE
rb_io_buffer_compare(VALUE self, VALUE other)
{
    const void *ptr1, *ptr2;
    size_t size1, size2;

    rb_io_buffer_get_bytes_for_reading(self, &amp;ptr1, &amp;size1);
    rb_io_buffer_get_bytes_for_reading(other, &amp;ptr2, &amp;size2);

    if (size1 &lt; size2) {
        return RB_INT2NUM(-1);
    }

    if (size1 &gt; size2) {
        return RB_INT2NUM(1);
    }

    return RB_INT2NUM(memcmp(ptr1, ptr2, size1));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-5E" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          source ^ mask &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate a new buffer the same size as the source by applying the binary XOR operation to the source, using the mask, repeating as necessary.</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>) <span class="ruby-operator">^</span> <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;\xFF\x00\x00\xFF&quot;</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000055a2d5d10480+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  ce 32 33 cb ca 36 37 c7 c6 30                   .23..67..0</span>
</pre>

                              <div class="method-source-code" id="5E-source">
            <pre>static VALUE
io_buffer_xor(VALUE self, VALUE mask)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    struct rb_io_buffer *mask_buffer = NULL;
    TypedData_Get_Struct(mask, struct rb_io_buffer, &amp;rb_io_buffer_type, mask_buffer);

    io_buffer_check_mask(mask_buffer);

    VALUE output = rb_io_buffer_new(NULL, buffer-&gt;size, io_flags_for_size(buffer-&gt;size));
    struct rb_io_buffer *output_buffer = NULL;
    TypedData_Get_Struct(output, struct rb_io_buffer, &amp;rb_io_buffer_type, output_buffer);

    memory_xor(output_buffer-&gt;base, buffer-&gt;base, buffer-&gt;size, mask_buffer-&gt;base, mask_buffer-&gt;size);

    return output;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-and-21" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          and!(mask) &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Modify the source buffer in place by applying the binary AND operation to the source, using the mask, repeating as necessary.</p>

<pre class="ruby"><span class="ruby-identifier">source</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>).<span class="ruby-identifier">dup</span> <span class="ruby-comment"># Make a read/write copy.</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a0d0c20+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  31 32 33 34 35 36 37 38 39 30                   1234567890</span>

<span class="ruby-identifier">source</span>.<span class="ruby-identifier">and!</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;\xFF\x00\x00\xFF&quot;</span>))
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a0d0c20+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  31 00 00 34 35 00 00 38 39 00                   1..45..89.</span>
</pre>

                              <div class="method-source-code" id="and-21-source">
            <pre>static VALUE
io_buffer_and_inplace(VALUE self, VALUE mask)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    struct rb_io_buffer *mask_buffer = NULL;
    TypedData_Get_Struct(mask, struct rb_io_buffer, &amp;rb_io_buffer_type, mask_buffer);

    io_buffer_check_mask(mask_buffer);
    io_buffer_check_overlaps(buffer, mask_buffer);

    void *base;
    size_t size;
    io_buffer_get_bytes_for_writing(buffer, &amp;base, &amp;size);

    memory_and_inplace(base, size, mask_buffer-&gt;base, mask_buffer-&gt;size);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-clear" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          clear(value = 0, [offset, [length]]) &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Fill buffer with <code>value</code>, starting with <code>offset</code> and going for <code>length</code> bytes.</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;test&#39;</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment">#   &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
<span class="ruby-comment">#   0x00000000  74 65 73 74         test</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">clear</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment">#   &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
<span class="ruby-comment">#   0x00000000  00 00 00 00         ....</span>

<span class="ruby-identifier">buf</span>.<span class="ruby-identifier">clear</span>(<span class="ruby-value">1</span>) <span class="ruby-comment"># fill with 1</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment">#   &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
<span class="ruby-comment">#   0x00000000  01 01 01 01         ....</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">clear</span>(<span class="ruby-value">2</span>, <span class="ruby-value">1</span>, <span class="ruby-value">2</span>) <span class="ruby-comment"># fill with 2, starting from offset 1, for 2 bytes</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment">#   &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
<span class="ruby-comment">#   0x00000000  01 02 02 01         ....</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">clear</span>(<span class="ruby-value">2</span>, <span class="ruby-value">1</span>) <span class="ruby-comment"># fill with 2, starting from offset 1</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment">#   &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
<span class="ruby-comment">#   0x00000000  01 02 02 02         ....</span>
</pre>

                              <div class="method-source-code" id="clear-source">
            <pre>static VALUE
io_buffer_clear(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 0, 3);

    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    uint8_t value = 0;
    if (argc &gt;= 1) {
        value = NUM2UINT(argv[0]);
    }

    size_t offset = 0;
    if (argc &gt;= 2) {
        offset = NUM2SIZET(argv[1]);
    }

    size_t length;
    if (argc &gt;= 3) {
        length = NUM2SIZET(argv[2]);
    }
    else {
        length = buffer-&gt;size - offset;
    }

    rb_io_buffer_clear(self, value, offset, length);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-copy" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          copy(source, [offset, [length, [source_offset]]]) &rarr; size
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Efficiently copy from a source <a href="Buffer.html"><code>IO::Buffer</code></a> into the buffer, at <code>offset</code> using <code>memcpy</code>. For copying <a href="../String.html"><code>String</code></a> instances, see <a href="Buffer.html#method-i-set_string"><code>set_string</code></a>.</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">32</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5ca22520+32 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................</span>
<span class="ruby-comment"># 0x00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................  *</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">copy</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;test&quot;</span>), <span class="ruby-value">8</span>)
<span class="ruby-comment"># =&gt; 4 -- size of buffer copied</span>
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5cf8fe40+32 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 00 00 00 00 00 74 65 73 74 00 00 00 00 ........test....</span>
<span class="ruby-comment"># 0x00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ *</span>
</pre>

<p><a href="Buffer.html#method-i-copy"><code>copy</code></a> can be used to put buffer into strings associated with buffer:</p>

<pre class="ruby"><span class="ruby-identifier">string</span>= <span class="ruby-string">&quot;buffer:    &quot;</span>
<span class="ruby-comment"># =&gt; &quot;buffer:    &quot;</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">copy</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;test&quot;</span>), <span class="ruby-value">5</span>)
<span class="ruby-comment"># =&gt; 4</span>
<span class="ruby-identifier">string</span>
<span class="ruby-comment"># =&gt; &quot;buffer:test&quot;</span>
</pre>

<p>Attempt to copy into a read-only buffer will fail:</p>

<pre class="ruby"><span class="ruby-constant">File</span>.<span class="ruby-identifier">write</span>(<span class="ruby-string">&#39;test.txt&#39;</span>, <span class="ruby-string">&#39;test&#39;</span>)
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">map</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;test.txt&#39;</span>), <span class="ruby-keyword">nil</span>, <span class="ruby-value">0</span>, <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span><span class="ruby-operator">::</span><span class="ruby-constant">READONLY</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">copy</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;test&quot;</span>), <span class="ruby-value">8</span>)
<span class="ruby-comment"># in `copy&#39;: Buffer is not writable! (IO::Buffer::AccessError)</span>
</pre>

<p>See <a href="Buffer.html#method-c-map"><code>::map</code></a> for details of creation of mutable file mappings, this will work:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">map</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;test.txt&#39;</span>, <span class="ruby-string">&#39;r+&#39;</span>))
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">copy</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;boom&quot;</span>), <span class="ruby-value">0</span>)
<span class="ruby-comment"># =&gt; 4</span>
<span class="ruby-constant">File</span>.<span class="ruby-identifier">read</span>(<span class="ruby-string">&#39;test.txt&#39;</span>)
<span class="ruby-comment"># =&gt; &quot;boom&quot;</span>
</pre>

<p>Attempt to copy the buffer which will need place outside of buffer’s bounds will fail:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">2</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">copy</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;test&#39;</span>), <span class="ruby-value">0</span>)
<span class="ruby-comment"># in `copy&#39;: Specified offset+length exceeds source size! (ArgumentError)</span>
</pre>

                              <div class="method-source-code" id="copy-source">
            <pre>static VALUE
io_buffer_copy(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, 4);

    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    VALUE source = argv[0];
    const void *source_base;
    size_t source_size;

    rb_io_buffer_get_bytes_for_reading(source, &amp;source_base, &amp;source_size);

    return io_buffer_copy_from(buffer, source_base, source_size, argc-1, argv+1);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-each" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          each(buffer_type, [offset, [count]]) {|offset, value| ...} &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          each(buffer_type, [offset, [count]]) &rarr; enumerator
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Iterates over the buffer, yielding each <code>value</code> of <code>buffer_type</code> starting from <code>offset</code>.</p>

<p>If <code>count</code> is given, only <code>count</code> values will be yielded.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;Hello World&quot;</span>).<span class="ruby-identifier">each</span>(<span class="ruby-value">:U8</span>, <span class="ruby-value">2</span>, <span class="ruby-value">2</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">offset</span>, <span class="ruby-identifier">value</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;#{offset}: #{value}&quot;</span>
<span class="ruby-keyword">end</span>
<span class="ruby-comment"># 2: 108</span>
<span class="ruby-comment"># 3: 108</span>
</pre>

                              <div class="method-source-code" id="each-source">
            <pre>static VALUE
io_buffer_each(int argc, VALUE *argv, VALUE self)
{
    RETURN_ENUMERATOR_KW(self, argc, argv, RB_NO_KEYWORDS);

    const void *base;
    size_t size;

    rb_io_buffer_get_bytes_for_reading(self, &amp;base, &amp;size);

    ID buffer_type;
    if (argc &gt;= 1) {
        buffer_type = RB_SYM2ID(argv[0]);
    }
    else {
        buffer_type = RB_IO_BUFFER_DATA_TYPE_U8;
    }

    size_t offset;
    if (argc &gt;= 2) {
        offset = NUM2SIZET(argv[1]);
    }
    else {
        offset = 0;
    }

    size_t count;
    if (argc &gt;= 3) {
        count = NUM2SIZET(argv[2]);
    }
    else {
        count = (size - offset) / io_buffer_buffer_type_size(buffer_type);
    }

    for (size_t i = 0; i &lt; count; i++) {
        size_t current_offset = offset;
        VALUE value = rb_io_buffer_get_value(base, size, buffer_type, &amp;offset);
        rb_yield_values(2, SIZET2NUM(current_offset), value);
    }

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-each_byte" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          each_byte([offset, [count]]) {|offset, byte| ...} &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          each_byte([offset, [count]]) &rarr; enumerator
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Iterates over the buffer, yielding each byte starting from <code>offset</code>.</p>

<p>If <code>count</code> is given, only <code>count</code> bytes will be yielded.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;Hello World&quot;</span>).<span class="ruby-identifier">each_byte</span>(<span class="ruby-value">2</span>, <span class="ruby-value">2</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">offset</span>, <span class="ruby-identifier">byte</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">puts</span> <span class="ruby-node">&quot;#{offset}: #{byte}&quot;</span>
<span class="ruby-keyword">end</span>
<span class="ruby-comment"># 2: 108</span>
<span class="ruby-comment"># 3: 108</span>
</pre>

                              <div class="method-source-code" id="each_byte-source">
            <pre>static VALUE
io_buffer_each_byte(int argc, VALUE *argv, VALUE self)
{
    RETURN_ENUMERATOR_KW(self, argc, argv, RB_NO_KEYWORDS);

    const void *base;
    size_t size;

    rb_io_buffer_get_bytes_for_reading(self, &amp;base, &amp;size);

    size_t offset;
    if (argc &gt;= 2) {
        offset = NUM2SIZET(argv[1]);
    }
    else {
        offset = 0;
    }

    size_t count;
    if (argc &gt;= 3) {
        count = NUM2SIZET(argv[2]);
    }
    else {
        count = (size - offset);
    }

    for (size_t i = 0; i &lt; count; i++) {
        unsigned char *value = (unsigned char *)base + i + offset;
        rb_yield(RB_INT2FIX(*value));
    }

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-empty-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          empty? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer has 0 size: it is created by <a href="Buffer.html#method-c-new"><code>::new</code></a> with size 0, or with <a href="Buffer.html#method-c-for"><code>::for</code></a> from an empty string. (Note that empty files can’t be mapped, so the buffer created with <a href="Buffer.html#method-c-map"><code>::map</code></a> will never be empty.)</p>

                              <div class="method-source-code" id="empty-3F-source">
            <pre>static VALUE
rb_io_buffer_empty_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;size == 0);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-external-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          external? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>The buffer is <em>external</em> if it references the memory which is not allocated or mapped by the buffer itself.</p>

<p>A buffer created using <a href="Buffer.html#method-c-for"><code>::for</code></a> has an external reference to the string’s memory.</p>

<p>External buffer can’t be resized.</p>

                              <div class="method-source-code" id="external-3F-source">
            <pre>static VALUE
rb_io_buffer_external_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;flags &amp; RB_IO_BUFFER_EXTERNAL);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-free" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          free &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer references memory, release it back to the operating system.</p>
<ul><li>
<p>for a <em>mapped</em> buffer (e.g. from file): unmap.</p>
</li><li>
<p>for a buffer created from scratch: free memory.</p>
</li><li>
<p>for a buffer created from string: undo the association.</p>
</li></ul>

<p>After the buffer is freed, no further operations can’t be performed on it.</p>

<p>You can resize a freed buffer to re-allocate it.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;test&#39;</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">free</span>
<span class="ruby-comment"># =&gt; #&lt;IO::Buffer 0x0000000000000000+0 NULL&gt;</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_value</span>(<span class="ruby-value">:U8</span>, <span class="ruby-value">0</span>)
<span class="ruby-comment"># in `get_value&#39;: The buffer is not allocated! (IO::Buffer::AllocationError)</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>
<span class="ruby-comment"># in `get_string&#39;: The buffer is not allocated! (IO::Buffer::AllocationError)</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">null?</span>
<span class="ruby-comment"># =&gt; true</span>
</pre>

                              <div class="method-source-code" id="free-source">
            <pre>VALUE
rb_io_buffer_free(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_LOCKED) {
        rb_raise(rb_eIOBufferLockedError, &quot;Buffer is locked!&quot;);
    }

    io_buffer_free(buffer);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-get_string" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          get_string([offset, [length, [encoding]]]) &rarr; string
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Read a chunk or all of the buffer into a string, in the specified <code>encoding</code>. If no encoding is provided <code>Encoding::BINARY</code> is used.</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;test&#39;</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>
<span class="ruby-comment"># =&gt; &quot;test&quot;</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>(<span class="ruby-value">2</span>)
<span class="ruby-comment"># =&gt; &quot;st&quot;</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">get_string</span>(<span class="ruby-value">2</span>, <span class="ruby-value">1</span>)
<span class="ruby-comment"># =&gt; &quot;s&quot;</span>
</pre>

                              <div class="method-source-code" id="get_string-source">
            <pre>static VALUE
io_buffer_get_string(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 0, 3);

    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    const void *base;
    size_t size;
    io_buffer_get_bytes_for_reading(buffer, &amp;base, &amp;size);

    size_t offset = 0;
    size_t length = size;
    rb_encoding *encoding = rb_ascii8bit_encoding();

    if (argc &gt;= 1) {
        offset = NUM2SIZET(argv[0]);
    }

    if (argc &gt;= 2 &amp;&amp; !RB_NIL_P(argv[1])) {
        length = NUM2SIZET(argv[1]);
    }
    else {
        length = size - offset;
    }

    if (argc &gt;= 3) {
        encoding = rb_find_encoding(argv[2]);
    }

    io_buffer_validate_range(buffer, offset, length);

    return rb_enc_str_new((const char*)base + offset, length, encoding);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-get_value" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          get_value(buffer_type, offset) &rarr; numeric
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Read from buffer a value of <code>type</code> at <code>offset</code>. <code>buffer_type</code> should be one of symbols:</p>
<ul><li>
<p><code>:U8</code>: unsigned integer, 1 byte</p>
</li><li>
<p><code>:S8</code>: signed integer, 1 byte</p>
</li><li>
<p><code>:u16</code>: unsigned integer, 2 bytes, little-endian</p>
</li><li>
<p><code>:U16</code>: unsigned integer, 2 bytes, big-endian</p>
</li><li>
<p><code>:s16</code>: signed integer, 2 bytes, little-endian</p>
</li><li>
<p><code>:S16</code>: signed integer, 2 bytes, big-endian</p>
</li><li>
<p><code>:u32</code>: unsigned integer, 4 bytes, little-endian</p>
</li><li>
<p><code>:U32</code>: unsigned integer, 4 bytes, big-endian</p>
</li><li>
<p><code>:s32</code>: signed integer, 4 bytes, little-endian</p>
</li><li>
<p><code>:S32</code>: signed integer, 4 bytes, big-endian</p>
</li><li>
<p><code>:u64</code>: unsigned integer, 8 bytes, little-endian</p>
</li><li>
<p><code>:U64</code>: unsigned integer, 8 bytes, big-endian</p>
</li><li>
<p><code>:s64</code>: signed integer, 8 bytes, little-endian</p>
</li><li>
<p><code>:S64</code>: signed integer, 8 bytes, big-endian</p>
</li><li>
<p><code>:f32</code>: float, 4 bytes, little-endian</p>
</li><li>
<p><code>:F32</code>: float, 4 bytes, big-endian</p>
</li><li>
<p><code>:f64</code>: double, 8 bytes, little-endian</p>
</li><li>
<p><code>:F64</code>: double, 8 bytes, big-endian</p>
</li></ul>

<p>A buffer type refers specifically to the type of binary buffer that is stored in the buffer. For example, a <code>:u32</code> buffer type is a 32-bit unsigned integer in little-endian format.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">string</span> = [<span class="ruby-value">1.5</span>].<span class="ruby-identifier">pack</span>(<span class="ruby-string">&#39;f&#39;</span>)
<span class="ruby-comment"># =&gt; &quot;\x00\x00\xC0?&quot;</span>
<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>).<span class="ruby-identifier">get_value</span>(<span class="ruby-value">:f32</span>, <span class="ruby-value">0</span>)
<span class="ruby-comment"># =&gt; 1.5</span>
</pre>

                              <div class="method-source-code" id="get_value-source">
            <pre>static VALUE
io_buffer_get_value(VALUE self, VALUE type, VALUE _offset)
{
    const void *base;
    size_t size;
    size_t offset = NUM2SIZET(_offset);

    rb_io_buffer_get_bytes_for_reading(self, &amp;base, &amp;size);

    return rb_io_buffer_get_value(base, size, RB_SYM2ID(type), &amp;offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-get_values" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          get_values(buffer_types, offset) &rarr; array
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Similar to <a href="Buffer.html#method-i-get_value"><code>get_value</code></a>, except that it can handle multiple buffer types and returns an array of values.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">string</span> = [<span class="ruby-value">1.5</span>, <span class="ruby-value">2.5</span>].<span class="ruby-identifier">pack</span>(<span class="ruby-string">&#39;ff&#39;</span>)
<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>).<span class="ruby-identifier">get_values</span>([<span class="ruby-value">:f32</span>, <span class="ruby-value">:f32</span>], <span class="ruby-value">0</span>)
<span class="ruby-comment"># =&gt; [1.5, 2.5]</span>
</pre>

                              <div class="method-source-code" id="get_values-source">
            <pre>static VALUE
io_buffer_get_values(VALUE self, VALUE buffer_types, VALUE _offset)
{
    size_t offset = NUM2SIZET(_offset);

    const void *base;
    size_t size;
    rb_io_buffer_get_bytes_for_reading(self, &amp;base, &amp;size);

    if (!RB_TYPE_P(buffer_types, T_ARRAY)) {
        rb_raise(rb_eArgError, &quot;Argument buffer_types should be an array!&quot;);
    }

    VALUE array = rb_ary_new_capa(RARRAY_LEN(buffer_types));

    for (long i = 0; i &lt; RARRAY_LEN(buffer_types); i++) {
        VALUE type = rb_ary_entry(buffer_types, i);
        VALUE value = rb_io_buffer_get_value(base, size, RB_SYM2ID(type), &amp;offset);
        rb_ary_push(array, value);
    }

    return array;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-hexdump" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">hexdump</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="hexdump-source">
            <pre>static VALUE
rb_io_buffer_hexdump(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    VALUE result = Qnil;

    if (io_buffer_validate(buffer) &amp;&amp; buffer-&gt;base) {
        result = rb_str_buf_new(buffer-&gt;size*3 + (buffer-&gt;size/16)*12 + 1);

        io_buffer_hexdump(result, 16, buffer-&gt;base, buffer-&gt;size, 1);
    }

    return result;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-initialize_copy" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          dup &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>
                      <div class="method-heading">
                        <span class="method-callseq">
                          clone &rarr; io_buffer
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Make an internal copy of the source buffer. Updates to the copy will not affect the source buffer.</p>

<pre class="ruby"><span class="ruby-identifier">source</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;Hello World&quot;</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007fd598466830+11 EXTERNAL READONLY SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  48 65 6c 6c 6f 20 57 6f 72 6c 64                Hello World</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-identifier">source</span>.<span class="ruby-identifier">dup</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000558cbec03320+11 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  48 65 6c 6c 6f 20 57 6f 72 6c 64                Hello World</span>
</pre>

                              <div class="method-source-code" id="initialize_copy-source">
            <pre>static VALUE
rb_io_buffer_initialize_copy(VALUE self, VALUE source)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    const void *source_base;
    size_t source_size;

    rb_io_buffer_get_bytes_for_reading(source, &amp;source_base, &amp;source_size);

    io_buffer_initialize(buffer, NULL, source_size, io_flags_for_size(source_size), Qnil);

    return io_buffer_copy_from(buffer, source_base, source_size, 0, NULL);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-inspect" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">inspect</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              

                              <div class="method-source-code" id="inspect-source">
            <pre>VALUE
rb_io_buffer_inspect(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    VALUE result = rb_io_buffer_to_s(self);

    if (io_buffer_validate(buffer)) {
        // Limit the maximum size generated by inspect.
        if (buffer-&gt;size &lt;= 256) {
            io_buffer_hexdump(result, 16, buffer-&gt;base, buffer-&gt;size, 0);
        }
    }

    return result;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-internal-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          internal? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer is <em>internal</em>, meaning it references memory allocated by the buffer itself.</p>

<p>An internal buffer is not associated with any external memory (e.g. string) or file mapping.</p>

<p>Internal buffers are created using <a href="Buffer.html#method-c-new"><code>::new</code></a> and is the default when the requested size is less than the <a href="Buffer.html#PAGE_SIZE"><code>IO::Buffer::PAGE_SIZE</code></a> and it was not requested to be mapped on creation.</p>

<p>Internal buffers can be resized, and such an operation will typically invalidate all slices, but not always.</p>

                              <div class="method-source-code" id="internal-3F-source">
            <pre>static VALUE
rb_io_buffer_internal_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;flags &amp; RB_IO_BUFFER_INTERNAL);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-locked" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          locked { ... }
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Allows to process a buffer in exclusive way, for concurrency-safety. While the block is performed, the buffer is considered locked, and no other code can enter the lock. Also, locked buffer can’t be changed with <a href="Buffer.html#method-i-resize"><code>resize</code></a> or <a href="Buffer.html#method-i-free"><code>free</code></a>.</p>

<p>The following operations acquire a lock: <a href="Buffer.html#method-i-resize"><code>resize</code></a>, <a href="Buffer.html#method-i-free"><code>free</code></a>.</p>

<p>Locking is not thread safe. It is designed as a safety net around non-blocking system calls. You can only share a buffer between threads with appropriate synchronisation techniques.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">4</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">locked?</span> <span class="ruby-comment">#=&gt; false</span>

<span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">schedule</span> <span class="ruby-keyword">do</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">locked</span> <span class="ruby-keyword">do</span>
    <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">io</span>) <span class="ruby-comment"># theoretical system call interface</span>
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>

<span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">schedule</span> <span class="ruby-keyword">do</span>
  <span class="ruby-comment"># in `locked&#39;: Buffer already locked! (IO::Buffer::LockedError)</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">locked</span> <span class="ruby-keyword">do</span>
    <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&quot;test&quot;</span>, <span class="ruby-value">0</span>)
  <span class="ruby-keyword">end</span>
<span class="ruby-keyword">end</span>
</pre>

                              <div class="method-source-code" id="locked-source">
            <pre>VALUE
rb_io_buffer_locked(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_LOCKED) {
        rb_raise(rb_eIOBufferLockedError, &quot;Buffer already locked!&quot;);
    }

    buffer-&gt;flags |= RB_IO_BUFFER_LOCKED;

    VALUE result = rb_yield(self);

    buffer-&gt;flags &amp;= ~RB_IO_BUFFER_LOCKED;

    return result;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-locked-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          locked? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer is <em>locked</em>, meaning it is inside <a href="Buffer.html#method-i-locked"><code>locked</code></a> block execution. Locked buffer can’t be resized or freed, and another lock can’t be acquired on it.</p>

<p>Locking is not thread safe, but is a semantic used to ensure buffers don’t move while being used by a system call.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">locked</span> <span class="ruby-keyword">do</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">io</span>) <span class="ruby-comment"># theoretical system call interface</span>
<span class="ruby-keyword">end</span>
</pre>

                              <div class="method-source-code" id="locked-3F-source">
            <pre>static VALUE
rb_io_buffer_locked_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;flags &amp; RB_IO_BUFFER_LOCKED);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-mapped-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          mapped? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer is <em>mapped</em>, meaning it references memory mapped by the buffer.</p>

<p>Mapped buffers are either anonymous, if created by <a href="Buffer.html#method-c-new"><code>::new</code></a> with the <a href="Buffer.html#MAPPED"><code>IO::Buffer::MAPPED</code></a> flag or if the size was at least <a href="Buffer.html#PAGE_SIZE"><code>IO::Buffer::PAGE_SIZE</code></a>, or backed by a file if created with <a href="Buffer.html#method-c-map"><code>::map</code></a>.</p>

<p>Mapped buffers can usually be resized, and such an operation will typically invalidate all slices, but not always.</p>

                              <div class="method-source-code" id="mapped-3F-source">
            <pre>static VALUE
rb_io_buffer_mapped_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;flags &amp; RB_IO_BUFFER_MAPPED);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-not-21" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          not! &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Modify the source buffer in place by applying the binary NOT operation to the source.</p>

<pre class="ruby"><span class="ruby-identifier">source</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>).<span class="ruby-identifier">dup</span> <span class="ruby-comment"># Make a read/write copy.</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a33a450+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  31 32 33 34 35 36 37 38 39 30                   1234567890</span>

<span class="ruby-identifier">source</span>.<span class="ruby-identifier">not!</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a33a450+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  ce cd cc cb ca c9 c8 c7 c6 cf                   ..........</span>
</pre>

                              <div class="method-source-code" id="not-21-source">
            <pre>static VALUE
io_buffer_not_inplace(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    void *base;
    size_t size;
    io_buffer_get_bytes_for_writing(buffer, &amp;base, &amp;size);

    memory_not_inplace(base, size);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-null-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          null? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer was freed with <a href="Buffer.html#method-i-free"><code>free</code></a> or was never allocated in the first place.</p>

                              <div class="method-source-code" id="null-3F-source">
            <pre>static VALUE
rb_io_buffer_null_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;base == NULL);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-or-21" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          or!(mask) &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Modify the source buffer in place by applying the binary OR operation to the source, using the mask, repeating as necessary.</p>

<pre class="ruby"><span class="ruby-identifier">source</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>).<span class="ruby-identifier">dup</span> <span class="ruby-comment"># Make a read/write copy.</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a272350+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  31 32 33 34 35 36 37 38 39 30                   1234567890</span>

<span class="ruby-identifier">source</span>.<span class="ruby-identifier">or!</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;\xFF\x00\x00\xFF&quot;</span>))
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a272350+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  ff 32 33 ff ff 36 37 ff ff 30                   .23..67..0</span>
</pre>

                              <div class="method-source-code" id="or-21-source">
            <pre>static VALUE
io_buffer_or_inplace(VALUE self, VALUE mask)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    struct rb_io_buffer *mask_buffer = NULL;
    TypedData_Get_Struct(mask, struct rb_io_buffer, &amp;rb_io_buffer_type, mask_buffer);

    io_buffer_check_mask(mask_buffer);
    io_buffer_check_overlaps(buffer, mask_buffer);

    void *base;
    size_t size;
    io_buffer_get_bytes_for_writing(buffer, &amp;base, &amp;size);

    memory_or_inplace(base, size, mask_buffer-&gt;base, mask_buffer-&gt;size);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-pread" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          pread(io, from, [length, [offset]]) &rarr; read length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Read at least <code>length</code> bytes from the <code>io</code> starting at the specified <code>from</code> position, into the buffer starting at <code>offset</code>. If an error occurs, return <code>-errno</code>.</p>

<p>If <code>length</code> is not given or <code>nil</code>, it defaults to the size of the buffer minus the offset, i.e. the entire buffer.</p>

<p>If <code>length</code> is zero, exactly one <code>pread</code> operation will occur.</p>

<p>If <code>offset</code> is not given, it defaults to zero, i.e. the beginning of the buffer.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;test&#39;</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">buffer</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">p</span> <span class="ruby-identifier">buffer</span>
  <span class="ruby-comment"># =&gt;</span>
  <span class="ruby-comment"># &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
  <span class="ruby-comment"># 0x00000000  74 65 73 74         test</span>

  <span class="ruby-comment"># take 2 bytes from the beginning of urandom,</span>
  <span class="ruby-comment"># put them in buffer starting from position 2</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">pread</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;/dev/urandom&#39;</span>, <span class="ruby-string">&#39;rb&#39;</span>), <span class="ruby-value">0</span>, <span class="ruby-value">2</span>, <span class="ruby-value">2</span>)
  <span class="ruby-identifier">p</span> <span class="ruby-identifier">buffer</span>
  <span class="ruby-comment"># =&gt;</span>
  <span class="ruby-comment"># &lt;IO::Buffer 0x00007f3bc65f2a58+4 EXTERNAL SLICE&gt;</span>
  <span class="ruby-comment"># 0x00000000  05 35 73 74         te.5</span>
<span class="ruby-keyword">end</span>
</pre>

                              <div class="method-source-code" id="pread-source">
            <pre>static VALUE
io_buffer_pread(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 2, 4);

    VALUE io = argv[0];
    rb_off_t from = NUM2OFFT(argv[1]);

    size_t length, offset;
    io_buffer_extract_arguments(self, argc-2, argv+2, &amp;length, &amp;offset);

    return rb_io_buffer_pread(self, io, from, length, offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-pwrite" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          pwrite(io, from, [length, [offset]]) &rarr; written length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Write at least <code>length</code> bytes from the buffer starting at <code>offset</code>, into the <code>io</code> starting at the specified <code>from</code> position. If an error occurs, return <code>-errno</code>.</p>

<p>If <code>length</code> is not given or <code>nil</code>, it defaults to the size of the buffer minus the offset, i.e. the entire buffer.</p>

<p>If <code>length</code> is zero, exactly one <code>pwrite</code> operation will occur.</p>

<p>If <code>offset</code> is not given, it defaults to zero, i.e. the beginning of the buffer.</p>

<p>If the <code>from</code> position is beyond the end of the file, the gap will be filled with null (0 value) bytes.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">out</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;output.txt&#39;</span>, <span class="ruby-constant">File</span><span class="ruby-operator">::</span><span class="ruby-constant">RDWR</span>) <span class="ruby-comment"># open for read/write, no truncation</span>
<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;1234567&#39;</span>).<span class="ruby-identifier">pwrite</span>(<span class="ruby-identifier">out</span>, <span class="ruby-value">2</span>, <span class="ruby-value">3</span>, <span class="ruby-value">1</span>)
</pre>

<p>This leads to <code>234</code> (3 bytes, starting from position 1) being written into <code>output.txt</code>, starting from file position 2.</p>

                              <div class="method-source-code" id="pwrite-source">
            <pre>static VALUE
io_buffer_pwrite(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 2, 4);

    VALUE io = argv[0];
    rb_off_t from = NUM2OFFT(argv[1]);

    size_t length, offset;
    io_buffer_extract_arguments(self, argc-2, argv+2, &amp;length, &amp;offset);

    return rb_io_buffer_pwrite(self, io, from, length, offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-read" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          read(io, [length, [offset]]) &rarr; read length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Read at least <code>length</code> bytes from the <code>io</code>, into the buffer starting at <code>offset</code>. If an error occurs, return <code>-errno</code>.</p>

<p>If <code>length</code> is not given or <code>nil</code>, it defaults to the size of the buffer minus the offset, i.e. the entire buffer.</p>

<p>If <code>length</code> is zero, exactly one <code>read</code> operation will occur.</p>

<p>If <code>offset</code> is not given, it defaults to zero, i.e. the beginning of the buffer.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;test&#39;</span>) <span class="ruby-keyword">do</span> <span class="ruby-operator">|</span><span class="ruby-identifier">buffer</span><span class="ruby-operator">|</span>
  <span class="ruby-identifier">p</span> <span class="ruby-identifier">buffer</span>
  <span class="ruby-comment"># =&gt;</span>
  <span class="ruby-comment"># &lt;IO::Buffer 0x00007fca40087c38+4 SLICE&gt;</span>
  <span class="ruby-comment"># 0x00000000  74 65 73 74         test</span>
  <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">read</span>(<span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;/dev/urandom&#39;</span>, <span class="ruby-string">&#39;rb&#39;</span>), <span class="ruby-value">2</span>)
  <span class="ruby-identifier">p</span> <span class="ruby-identifier">buffer</span>
  <span class="ruby-comment"># =&gt;</span>
  <span class="ruby-comment"># &lt;IO::Buffer 0x00007f3bc65f2a58+4 EXTERNAL SLICE&gt;</span>
  <span class="ruby-comment"># 0x00000000  05 35 73 74         .5st</span>
<span class="ruby-keyword">end</span>
</pre>

                              <div class="method-source-code" id="read-source">
            <pre>static VALUE
io_buffer_read(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, 3);

    VALUE io = argv[0];

    size_t length, offset;
    io_buffer_extract_arguments(self, argc-1, argv+1, &amp;length, &amp;offset);

    return rb_io_buffer_read(self, io, length, offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-readonly-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          readonly? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer is <em>read only</em>, meaning the buffer cannot be modified using <a href="Buffer.html#method-i-set_value"><code>set_value</code></a>, <a href="Buffer.html#method-i-set_string"><code>set_string</code></a> or <a href="Buffer.html#method-i-copy"><code>copy</code></a> and similar.</p>

<p>Frozen strings and read-only files create read-only buffers.</p>

                              <div class="method-source-code" id="readonly-3F-source">
            <pre>static VALUE
io_buffer_readonly_p(VALUE self)
{
    return RBOOL(rb_io_buffer_readonly_p(self));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-resize" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          resize(new_size) &rarr; self
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Resizes a buffer to a <code>new_size</code> bytes, preserving its content. Depending on the old and new size, the memory area associated with the buffer might be either extended, or rellocated at different address with content being copied.</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">4</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&quot;test&quot;</span>, <span class="ruby-value">0</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">resize</span>(<span class="ruby-value">8</span>) <span class="ruby-comment"># resize to 8 bytes</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5d1a1630+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  74 65 73 74 00 00 00 00                         test....</span>
</pre>

<p>External buffer (created with <a href="Buffer.html#method-c-for"><code>::for</code></a>), and locked buffer can not be resized.</p>

                              <div class="method-source-code" id="resize-source">
            <pre>static VALUE
io_buffer_resize(VALUE self, VALUE size)
{
    rb_io_buffer_resize(self, NUM2SIZET(size));

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-set_string" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          set_string(string, [offset, [length, [source_offset]]]) &rarr; size
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Efficiently copy buffer from a source <a href="../String.html"><code>String</code></a> into the buffer, at <code>offset</code> using <code>memcpy</code>.</p>

<pre class="ruby"><span class="ruby-identifier">buf</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">8</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000557412714a20+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 00 00 00 00 00                         ........</span>

<span class="ruby-comment"># set buffer starting from offset 1, take 2 bytes starting from string&#39;s</span>
<span class="ruby-comment"># second</span>
<span class="ruby-identifier">buf</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;test&#39;</span>, <span class="ruby-value">1</span>, <span class="ruby-value">2</span>, <span class="ruby-value">1</span>)
<span class="ruby-comment"># =&gt; 2</span>
<span class="ruby-identifier">buf</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000557412714a20+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 65 73 00 00 00 00 00                         .es.....</span>
</pre>

<p>See also <a href="Buffer.html#method-i-copy"><code>copy</code></a> for examples of how buffer writing might be used for changing associated strings and files.</p>

                              <div class="method-source-code" id="set_string-source">
            <pre>static VALUE
io_buffer_set_string(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, 4);

    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    VALUE string = rb_str_to_str(argv[0]);

    const void *source_base = RSTRING_PTR(string);
    size_t source_size = RSTRING_LEN(string);

    return io_buffer_copy_from(buffer, source_base, source_size, argc-1, argv+1);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-set_value" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          set_value(type, offset, value) &rarr; offset
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Write to a buffer a <code>value</code> of <code>type</code> at <code>offset</code>. <code>type</code> should be one of symbols described in <a href="Buffer.html#method-i-get_value"><code>get_value</code></a>.</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">8</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5c9a2d50+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 00 00 00 00 00</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_value</span>(<span class="ruby-value">:U8</span>, <span class="ruby-value">1</span>, <span class="ruby-value">111</span>)
<span class="ruby-comment"># =&gt; 1</span>

<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5c9a2d50+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 6f 00 00 00 00 00 00                         .o......</span>
</pre>

<p>Note that if the <code>type</code> is integer and <code>value</code> is <a href="../Float.html"><code>Float</code></a>, the implicit truncation is performed:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">8</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_value</span>(<span class="ruby-value">:U32</span>, <span class="ruby-value">0</span>, <span class="ruby-value">2.5</span>)

<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000555f5c9a2d50+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  00 00 00 02 00 00 00 00</span>
<span class="ruby-comment">#                      ^^ the same as if we&#39;d pass just integer 2</span>
</pre>

                              <div class="method-source-code" id="set_value-source">
            <pre>static VALUE
io_buffer_set_value(VALUE self, VALUE type, VALUE _offset, VALUE value)
{
    void *base;
    size_t size;
    size_t offset = NUM2SIZET(_offset);

    rb_io_buffer_get_bytes_for_writing(self, &amp;base, &amp;size);

    rb_io_buffer_set_value(base, size, RB_SYM2ID(type), &amp;offset, value);

    return SIZET2NUM(offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-set_values" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          set_values(buffer_types, offset, values) &rarr; offset
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Write <code>values</code> of <code>buffer_types</code> at <code>offset</code> to the buffer. <code>buffer_types</code> should be an array of symbols as described in <a href="Buffer.html#method-i-get_value"><code>get_value</code></a>. <code>values</code> should be an array of values to write.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">8</span>)
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">set_values</span>([<span class="ruby-value">:U8</span>, <span class="ruby-value">:U16</span>], <span class="ruby-value">0</span>, [<span class="ruby-value">1</span>, <span class="ruby-value">2</span>])
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x696f717561746978+8 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  01 00 02 00 00 00 00 00                         ........</span>
</pre>

                              <div class="method-source-code" id="set_values-source">
            <pre>static VALUE
io_buffer_set_values(VALUE self, VALUE buffer_types, VALUE _offset, VALUE values)
{
    if (!RB_TYPE_P(buffer_types, T_ARRAY)) {
        rb_raise(rb_eArgError, &quot;Argument buffer_types should be an array!&quot;);
    }

    if (!RB_TYPE_P(values, T_ARRAY)) {
        rb_raise(rb_eArgError, &quot;Argument values should be an array!&quot;);
    }

    if (RARRAY_LEN(buffer_types) != RARRAY_LEN(values)) {
        rb_raise(rb_eArgError, &quot;Argument buffer_types and values should have the same length!&quot;);
    }

    size_t offset = NUM2SIZET(_offset);

    void *base;
    size_t size;
    rb_io_buffer_get_bytes_for_writing(self, &amp;base, &amp;size);

    for (long i = 0; i &lt; RARRAY_LEN(buffer_types); i++) {
        VALUE type = rb_ary_entry(buffer_types, i);
        VALUE value = rb_ary_entry(values, i);
        rb_io_buffer_set_value(base, size, RB_SYM2ID(type), &amp;offset, value);
    }

    return SIZET2NUM(offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-shared-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          shared? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>If the buffer is <em>shared</em>, meaning it references memory that can be shared with other processes (and thus might change without being modified locally).</p>

                              <div class="method-source-code" id="shared-3F-source">
            <pre>static VALUE
rb_io_buffer_shared_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(buffer-&gt;flags &amp; RB_IO_BUFFER_SHARED);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-size" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          size &rarr; integer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns the size of the buffer that was explicitly set (on creation with <a href="Buffer.html#method-c-new"><code>::new</code></a> or on <a href="Buffer.html#method-i-resize"><code>resize</code></a>), or deduced on buffer’s creation from string or file.</p>

                              <div class="method-source-code" id="size-source">
            <pre>VALUE
rb_io_buffer_size(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return SIZET2NUM(buffer-&gt;size);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-slice" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          slice([offset = 0, [length]]) &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Produce another <a href="Buffer.html"><code>IO::Buffer</code></a> which is a slice (or view into) the current one starting at <code>offset</code> bytes and going for <code>length</code> bytes.</p>

<p>The slicing happens without copying of memory, and the slice keeps being associated with the original buffer’s source (string, or file), if any.</p>

<p>If the offset is not given, it will be zero. If the offset is negative, it will raise an <a href="../ArgumentError.html"><code>ArgumentError</code></a>.</p>

<p>If the length is not given, the slice will be as long as the original buffer minus the specified offset. If the length is negative, it will raise an <a href="../ArgumentError.html"><code>ArgumentError</code></a>.</p>

<p>Raises <a href="../RuntimeError.html"><code>RuntimeError</code></a> if the <code>offset+length</code> is out of the current buffer’s bounds.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">string</span> = <span class="ruby-string">&#39;test&#39;</span>
<span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-identifier">string</span>)

<span class="ruby-identifier">slice</span> = <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">slice</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000000108338e68+4 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  74 65 73 74                                     test</span>

<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">slice</span>(<span class="ruby-value">2</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000000108338e6a+2 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  73 74                                           st</span>

<span class="ruby-identifier">slice</span> = <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">slice</span>(<span class="ruby-value">1</span>, <span class="ruby-value">2</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007fc3d34ebc49+2 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  65 73                                           es</span>

<span class="ruby-comment"># Put &quot;o&quot; into 0s position of the slice</span>
<span class="ruby-identifier">slice</span>.<span class="ruby-identifier">set_string</span>(<span class="ruby-string">&#39;o&#39;</span>, <span class="ruby-value">0</span>)
<span class="ruby-identifier">slice</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007fc3d34ebc49+2 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  6f 73                                           os</span>

<span class="ruby-comment"># it is also visible at position 1 of the original buffer</span>
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007fc3d31e2d80+4 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  74 6f 73 74                                     tost</span>

<span class="ruby-comment"># ...and original string</span>
<span class="ruby-identifier">string</span>
<span class="ruby-comment"># =&gt; tost</span>
</pre>

                              <div class="method-source-code" id="slice-source">
            <pre>static VALUE
io_buffer_slice(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 0, 2);

    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    size_t offset = 0, length = 0;

    if (argc &gt; 0) {
        if (rb_int_negative_p(argv[0])) {
            rb_raise(rb_eArgError, &quot;Offset can&#39;t be negative!&quot;);
        }

        offset = NUM2SIZET(argv[0]);
    }

    if (argc &gt; 1) {
        if (rb_int_negative_p(argv[1])) {
            rb_raise(rb_eArgError, &quot;Length can&#39;t be negative!&quot;);
        }

        length = NUM2SIZET(argv[1]);
    }
    else {
        length = buffer-&gt;size - offset;
    }

    return rb_io_buffer_slice(buffer, self, offset, length);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-to_s" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          to_s &rarr; string
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Short representation of the buffer. It includes the address, size and symbolic flags. This format is subject to change.</p>

<pre class="ruby"><span class="ruby-identifier">puts</span> <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">4</span>) <span class="ruby-comment"># uses to_s internally</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000055769f41b1a0+4 INTERNAL&gt;</span>
</pre>

                              <div class="method-source-code" id="to_s-source">
            <pre>VALUE
rb_io_buffer_to_s(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    VALUE result = rb_str_new_cstr(&quot;#&lt;&quot;);

    rb_str_append(result, rb_class_name(CLASS_OF(self)));
    rb_str_catf(result, &quot; %p+%&quot;PRIdSIZE, buffer-&gt;base, buffer-&gt;size);

    if (buffer-&gt;base == NULL) {
        rb_str_cat2(result, &quot; NULL&quot;);
    }

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_EXTERNAL) {
        rb_str_cat2(result, &quot; EXTERNAL&quot;);
    }

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_INTERNAL) {
        rb_str_cat2(result, &quot; INTERNAL&quot;);
    }

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_MAPPED) {
        rb_str_cat2(result, &quot; MAPPED&quot;);
    }

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_SHARED) {
        rb_str_cat2(result, &quot; SHARED&quot;);
    }

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_LOCKED) {
        rb_str_cat2(result, &quot; LOCKED&quot;);
    }

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_READONLY) {
        rb_str_cat2(result, &quot; READONLY&quot;);
    }

    if (buffer-&gt;source != Qnil) {
        rb_str_cat2(result, &quot; SLICE&quot;);
    }

    if (!io_buffer_validate(buffer)) {
        rb_str_cat2(result, &quot; INVALID&quot;);
    }

    return rb_str_cat2(result, &quot;&gt;&quot;);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-transfer" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          transfer &rarr; new_io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Transfers ownership to a new buffer, deallocating the current one.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">buffer</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">new</span>(<span class="ruby-string">&#39;test&#39;</span>)
<span class="ruby-identifier">other</span> = <span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">transfer</span>
<span class="ruby-identifier">other</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x00007f136a15f7b0+4 SLICE&gt;</span>
<span class="ruby-comment"># 0x00000000  74 65 73 74                                     test</span>
<span class="ruby-identifier">buffer</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000000000000000+0 NULL&gt;</span>
<span class="ruby-identifier">buffer</span>.<span class="ruby-identifier">null?</span>
<span class="ruby-comment"># =&gt; true</span>
</pre>

                              <div class="method-source-code" id="transfer-source">
            <pre>VALUE
rb_io_buffer_transfer(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    if (buffer-&gt;flags &amp; RB_IO_BUFFER_LOCKED) {
        rb_raise(rb_eIOBufferLockedError, &quot;Cannot transfer ownership of locked buffer!&quot;);
    }

    VALUE instance = rb_io_buffer_type_allocate(rb_class_of(self));
    struct rb_io_buffer *transferred;
    TypedData_Get_Struct(instance, struct rb_io_buffer, &amp;rb_io_buffer_type, transferred);

    *transferred = *buffer;
    io_buffer_zero(buffer);

    return instance;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-valid-3F" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          valid? &rarr; true or false
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns whether the buffer buffer is accessible.</p>

<p>A buffer becomes invalid if it is a slice of another buffer which has been freed.</p>

                              <div class="method-source-code" id="valid-3F-source">
            <pre>static VALUE
rb_io_buffer_valid_p(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    return RBOOL(io_buffer_validate(buffer));
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-values" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          values(buffer_type, [offset, [count]]) &rarr; array
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Returns an array of values of <code>buffer_type</code> starting from <code>offset</code>.</p>

<p>If <code>count</code> is given, only <code>count</code> values will be returned.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;Hello World&quot;</span>).<span class="ruby-identifier">values</span>(<span class="ruby-value">:U8</span>, <span class="ruby-value">2</span>, <span class="ruby-value">2</span>)
<span class="ruby-comment"># =&gt; [108, 108]</span>
</pre>

                              <div class="method-source-code" id="values-source">
            <pre>static VALUE
io_buffer_values(int argc, VALUE *argv, VALUE self)
{
    const void *base;
    size_t size;

    rb_io_buffer_get_bytes_for_reading(self, &amp;base, &amp;size);

    ID buffer_type;
    if (argc &gt;= 1) {
        buffer_type = RB_SYM2ID(argv[0]);
    }
    else {
        buffer_type = RB_IO_BUFFER_DATA_TYPE_U8;
    }

    size_t offset;
    if (argc &gt;= 2) {
        offset = NUM2SIZET(argv[1]);
    }
    else {
        offset = 0;
    }

    size_t count;
    if (argc &gt;= 3) {
        count = NUM2SIZET(argv[2]);
    }
    else {
        count = (size - offset) / io_buffer_buffer_type_size(buffer_type);
    }

    VALUE array = rb_ary_new_capa(count);

    for (size_t i = 0; i &lt; count; i++) {
        VALUE value = rb_io_buffer_get_value(base, size, buffer_type, &amp;offset);
        rb_ary_push(array, value);
    }

    return array;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-write" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          write(io, [length, [offset]]) &rarr; written length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Write at least <code>length</code> bytes from the buffer starting at <code>offset</code>, into the <code>io</code>. If an error occurs, return <code>-errno</code>.</p>

<p>If <code>length</code> is not given or <code>nil</code>, it defaults to the size of the buffer minus the offset, i.e. the entire buffer.</p>

<p>If <code>length</code> is zero, exactly one <code>write</code> operation will occur.</p>

<p>If <code>offset</code> is not given, it defaults to zero, i.e. the beginning of the buffer.</p>

<p>Example:</p>

<pre class="ruby"><span class="ruby-identifier">out</span> = <span class="ruby-constant">File</span>.<span class="ruby-identifier">open</span>(<span class="ruby-string">&#39;output.txt&#39;</span>, <span class="ruby-string">&#39;wb&#39;</span>)
<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&#39;1234567&#39;</span>).<span class="ruby-identifier">write</span>(<span class="ruby-identifier">out</span>, <span class="ruby-value">3</span>)
</pre>

<p>This leads to <code>123</code> being written into <code>output.txt</code></p>

                              <div class="method-source-code" id="write-source">
            <pre>static VALUE
io_buffer_write(int argc, VALUE *argv, VALUE self)
{
    rb_check_arity(argc, 1, 3);

    VALUE io = argv[0];

    size_t length, offset;
    io_buffer_extract_arguments(self, argc-1, argv+1, &amp;length, &amp;offset);

    return rb_io_buffer_write(self, io, length, offset);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-xor-21" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          xor!(mask) &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Modify the source buffer in place by applying the binary XOR operation to the source, using the mask, repeating as necessary.</p>

<pre class="ruby"><span class="ruby-identifier">source</span> = <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>).<span class="ruby-identifier">dup</span> <span class="ruby-comment"># Make a read/write copy.</span>
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a25b3e0+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  31 32 33 34 35 36 37 38 39 30                   1234567890</span>

<span class="ruby-identifier">source</span>.<span class="ruby-identifier">xor!</span>(<span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;\xFF\x00\x00\xFF&quot;</span>))
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000056307a25b3e0+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  ce 32 33 cb ca 36 37 c7 c6 30                   .23..67..0</span>
</pre>

                              <div class="method-source-code" id="xor-21-source">
            <pre>static VALUE
io_buffer_xor_inplace(VALUE self, VALUE mask)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    struct rb_io_buffer *mask_buffer = NULL;
    TypedData_Get_Struct(mask, struct rb_io_buffer, &amp;rb_io_buffer_type, mask_buffer);

    io_buffer_check_mask(mask_buffer);
    io_buffer_check_overlaps(buffer, mask_buffer);

    void *base;
    size_t size;
    io_buffer_get_bytes_for_writing(buffer, &amp;base, &amp;size);

    memory_xor_inplace(base, size, mask_buffer-&gt;base, mask_buffer-&gt;size);

    return self;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-7C" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          source | mask &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate a new buffer the same size as the source by applying the binary OR operation to the source, using the mask, repeating as necessary.</p>

<pre class="ruby"><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>) <span class="ruby-operator">|</span> <span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;\xFF\x00\x00\xFF&quot;</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x0000561785ae3480+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  ff 32 33 ff ff 36 37 ff ff 30                   .23..67..0</span>
</pre>

                              <div class="method-source-code" id="7C-source">
            <pre>static VALUE
io_buffer_or(VALUE self, VALUE mask)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    struct rb_io_buffer *mask_buffer = NULL;
    TypedData_Get_Struct(mask, struct rb_io_buffer, &amp;rb_io_buffer_type, mask_buffer);

    io_buffer_check_mask(mask_buffer);

    VALUE output = rb_io_buffer_new(NULL, buffer-&gt;size, io_flags_for_size(buffer-&gt;size));
    struct rb_io_buffer *output_buffer = NULL;
    TypedData_Get_Struct(output, struct rb_io_buffer, &amp;rb_io_buffer_type, output_buffer);

    memory_or(output_buffer-&gt;base, buffer-&gt;base, buffer-&gt;size, mask_buffer-&gt;base, mask_buffer-&gt;size);

    return output;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-~" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          ~source &rarr; io_buffer
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Generate a new buffer the same size as the source by applying the binary NOT operation to the source.</p>

<pre class="ruby"><span class="ruby-operator">~</span><span class="ruby-constant">IO</span><span class="ruby-operator">::</span><span class="ruby-constant">Buffer</span>.<span class="ruby-identifier">for</span>(<span class="ruby-string">&quot;1234567890&quot;</span>)
<span class="ruby-comment"># =&gt;</span>
<span class="ruby-comment"># #&lt;IO::Buffer 0x000055a5ac42f120+10 INTERNAL&gt;</span>
<span class="ruby-comment"># 0x00000000  ce cd cc cb ca c9 c8 c7 c6 cf                   ..........</span>
</pre>

                              <div class="method-source-code" id="~-source">
            <pre>static VALUE
io_buffer_not(VALUE self)
{
    struct rb_io_buffer *buffer = NULL;
    TypedData_Get_Struct(self, struct rb_io_buffer, &amp;rb_io_buffer_type, buffer);

    VALUE output = rb_io_buffer_new(NULL, buffer-&gt;size, io_flags_for_size(buffer-&gt;size));
    struct rb_io_buffer *output_buffer = NULL;
    TypedData_Get_Struct(output, struct rb_io_buffer, &amp;rb_io_buffer_type, output_buffer);

    memory_not(output_buffer-&gt;base, buffer-&gt;base, buffer-&gt;size);

    return output;
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

              </section>
              </main>



            </div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>.</p><p><a href="https://jamesbritt.bandcamp.com/">Maximum R+D</a>.  </p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

